<?php

	class SmuoiMime{
		
		static function read_file($fp){
			$basename = basename($fp);
			$byxtn = SmuoiMime::xtn_switch(SmuoiMime::xtn_of($basename));
			if($mime = SmuoiMime::solve($fp, &$solution)){
				if(SmuoiMime::is_spoof($mime)) return $byxtn;
				if(!in_array($byxtn, array($mime, 'application/octet-stream')))
					error_log("Mime solution '$solution' read $basename as $mime (expected $byxtn)");
				return $mime;
			}
			error_log("You have no functioning mime solution installed. Trusting user input ($basename)...");
			return $byxtn;
		}
		
		static function xtn_of($file){
			return substr(strrchr(basename($file), '.'), 1);
		}
		
		static function xtn_switch($xtn){
			switch(strtolower($xtn)){	
				case 'jpeg':
				case 'jpg':
					return "image/jpeg";
				case 'gif':
				case 'png':
					return "image/$xtn";
				case 'html':
				case 'htm':
					return 'text/html';
				case 'js':
					return 'application/javascript';
				case 'xml':
				case 'css':
					return "text/$xtn";
				case 'txt':
				case 'log':
				case 'htaccess':
					return "text/plain";
				case 'json':
					return 'application/json';
				case 'mp3':
					return 'audio/mpeg';
				case 'wav':
					return 'audio/x-wav';
				case 'dtd':
					return 'application/xml-dtd';
				default:
					return 'application/octet-stream';
			}
		}
		
		static function is_spoof($type){
			switch($type){
				case 'application/x-empty':
					return true;
			}
			return false;
		}
		
		static function media($type){
			return strtolower(trim(array_shift(explode('/', $type))));
		}
	
		static function subtype($type){
			return strtolower(trim(array_shift(explode(';', array_pop(explode('/', $type))))));
		}
		
		static function clean($type){
			// If it's some stupid string like 'very short file (no magic)' just return false
			if(!strpos($type, '/')) return false;
			return SmuoiMime::media($type).'/'.SmuoiMime::subtype($type);
		}
	
		static function solve($file, &$solution){
			if(!is_file($file) || !is_readable($file)) return false;
					
			if(function_exists('finfo_file')) {
				$finfo = finfo_open(FILEINFO_MIME);
				$type  = finfo_file($finfo, $file);
				finfo_close($finfo);
				if($type){
					$solution = 'finfo_file';
					return SmuoiMime::clean($type);
				}
			}
	
			if(function_exists('mime_content_type')){
				if($type = mime_content_type($file)){
					$solution = 'mime_content_type';
					return SmuoiMime::clean($type);
				}
			}
			
			if(defined('PEAR_DIR')){
				@include_once 'System/Command.php';
				if(class_exists('System_Command')){
					if($type = SmuoiMime::pearSystemCmd($file)){
						$solution = 'pear_system_command';
						return SmuoiMime::clean($type);
					}
				}
			}
			return false;
		}	
	
		static function pearSystemCmd($file){
			require_once 'PEAR.php';
			// Make sure we have the 'file' command.
			$fileCmd = &PEAR::getStaticProperty('MimeDetect', 'fileCmd');
			$fileCmd = 'file';
			$cmd = new System_Command();	
			if (!$cmd->which($fileCmd)) {
				unset($cmd);
				return false;
			}
			$cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file));
			$res = $cmd->execute();
			unset($cmd);
			return $res;
		}
	}


